package com.yonyou.pmclouds.outter.enterprise;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.enterprise.entity.*;
import com.yonyou.yht.sdk.EnterpriseCenter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;

@Slf4j
@Component
public class EnterpriseInfoServerQuery {
    private ObjectMapper mapper;

    public EnterpriseInfoServerQuery() {
        mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 根据id获取企业信息
     */
    public EnterpriseInfo queryEnterpriseById(String id) {
        String result = EnterpriseCenter.getEnInfo(id);
        if (StringUtils.isEmpty(result)) {
            return null;
        }
        try {
            EnterpriseResult ent = mapper.readValue(result, EnterpriseResult.class);
            return ent.getEninfo();
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 根据id获取企业信息
     */
    public Map<String, EnterpriseInfo> queryEnterpriseByIds(String[] ids) {
        Map<String, EnterpriseInfo> result = new HashMap<>();
        if (ArrayUtils.isEmpty(ids)) {
            return result;
        }
        for (String id : ids) {

            if (StringUtils.isEmpty(id))
                continue;
            result.put(id, null);
        }
        String infoString = EnterpriseCenter.batchGeEnterInfos(new ArrayList<String>(result.keySet()));
        if (StringUtils.isEmpty(infoString)) {
            return result;
        }
        try {
            EnterpriseBatchResult ents = mapper.readValue(infoString, EnterpriseBatchResult.class);
            if (ArrayUtils.isEmpty(ents.getData())) {
                return result;
            }
            for (EnterpriseInfo ent : ents.getData()) {
                result.put(ent.getId(), ent);
            }
        } catch (IOException e) {
            return result;
        }

        return result;
    }

    /**
     * 根据名称查找企业
     */
    public EnterpriseInfo[] searchEnterprise(String name) {
        String result = EnterpriseCenter.searchEnterByName(name);
        if (StringUtils.isEmpty(result)) {
            return null;
        }
        try {
            EnterpriseSearchResult ents = mapper.readValue(result, EnterpriseSearchResult.class);
            return ents.getEnterprises();
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 获取单个用户的企业
     */
    public EnterpriseInfo[] getEnterprisesOfUser(String userid) {
        String result = EnterpriseCenter.getOwnedEnterListByUserId(userid);
        if (StringUtils.isEmpty(result)) {
            return null;
        }
        try {
            UserEnterpriseList userEnterpriseList = mapper.readValue(result, UserEnterpriseList.class);
            return userEnterpriseList.getEnlist();
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 获取用户对应的企业
     */
    public Map<String, EnterpriseInfo[]> getEnterprisesOfUsers(String[] userids) {
        Map<String, EnterpriseInfo[]> userEntMap = new HashMap<>(userids.length);
        String result = EnterpriseCenter.batchGetUserOwenedEnters(Arrays.asList(userids));
        try {
            BatchUserEnterpriseList userEnterpriseList = mapper.readValue(result, BatchUserEnterpriseList.class);
            BatchUserEnterpriseList.UserEnterprise[] userEnts = userEnterpriseList.getData();
            for (BatchUserEnterpriseList.UserEnterprise userEnt : userEnts) {
                EnterpriseBriefInfo[] breifInfos = userEnt.getEnterBriefInfos();
                if (ArrayUtils.isEmpty(breifInfos)) {
                    continue;
                }
                EnterpriseInfo[] infos = new EnterpriseInfo[breifInfos.length];
                for (int i = 0; i < breifInfos.length; i++) {
                    infos[i] = new EnterpriseInfo();
                    infos[i].setName(breifInfos[i].getEnterName());
                    infos[i].setId(breifInfos[i].getEnterId());
                }
                userEntMap.put(userEnt.getUserId(), infos);
            }
        } catch (IOException e) {
            return null;
        }

        return userEntMap;
    }

    public void tranEntInfoField(Object[] beans, String[] entIdFields, String[] entNameFields) {
        tranEntInfoField(beans, beans, entIdFields, entNameFields);
    }

    public void tranEntInfoField(Object[] srcs, Object[] dests,
                                 String[] entIdFields, String[] entNameFields) {
        if (ArrayUtils.isEmpty(srcs) || ArrayUtils.isEmpty(dests) || srcs.length != dests.length) {
            return;
        }
        Set<String> userIds = new HashSet<>();
        for (String userIdField : entIdFields) {
            Method read = BeanHelper.getGetMethod(srcs[0], userIdField);
            if (read == null) {
                continue;
            }
            for (Object src : srcs) {
                try {
                    String id = (String) read.invoke(src);
                    userIds.add(id);
                } catch (Exception e) {
                    log.error("read userid error {}", read);
                }
            }
        }
        Map<String, EnterpriseInfo> userIdNameMap = queryEnterpriseByIds(userIds.toArray(new String[userIds.size()]));
        for (int i = 0; i < entIdFields.length; i++) {
            Method write = BeanHelper.getSetMethod(dests[0], entNameFields[i]);
            Method read = BeanHelper.getGetMethod(srcs[0], entIdFields[i]);
            if (write == null) {
                continue;
            }
            for (int j = 0; j < srcs.length; j++) {
                try {
                    EnterpriseInfo info = userIdNameMap.get(read.invoke(srcs[j]));
                    if (info != null) {
                        write.invoke(dests[j], info.getName());
                    }
                } catch (Exception e) {
                    log.error("read userid error {}", write);
                }
            }
        }
    }
}
